package de.htwg_konstanz.infen.aufg3;

import java.io.File;
import java.io.FileOutputStream;
import java.util.List;
import java.util.Map;

import javax.xml.XMLConstants;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;
import javax.xml.validation.Schema;
import javax.xml.validation.SchemaFactory;

import de.htwg_konstanz.infen.aufg3.inputXML.jaxbGenerated.ObjectFactory;
import de.htwg_konstanz.infen.aufg3.inputXML.jaxbGenerated.TElement;
import de.htwg_konstanz.infen.aufg3.inputXML.jaxbGenerated.TOccurrence;
import de.htwg_konstanz.infen.aufg3.inputXML.jaxbGenerated.TXmlDataGuide;

public class CreateOutput {
	private String xmlFile = "";
	private String xsdFile = "";
	private TXmlDataGuide txdg;

	public CreateOutput(String xsdFile, String xmlOutputFile) {
		this.xmlFile = xmlOutputFile;
		this.xsdFile = xsdFile;
	}

	public void go(Map<String, CustomHashMapValueItem> elementMap2) {
		Object[] aArray = elementMap2.entrySet().toArray();

		ObjectFactory of = new ObjectFactory();
		txdg = of.createTXmlDataGuide();
		int maxLevel = getMaxLevel(aArray);

		for (int i = 0; i < elementMap2.size(); i++) {
			String[] test = aArray[i].toString().split("=");

			if (getLevelOfAttribute(test[0]) == 1) {
				TElement te = of.createTElement();
				te.setName(getLastAttribute(test[0]));
				te.setOccurrence(TOccurrence.fromValue(test[1]));
				txdg.setElement(te);
			}
		}

		for (int i = 2; i <= maxLevel; i++) {
			for (int j = 0; j < elementMap2.size(); j++) {
				String[] test = aArray[j].toString().split("=");
				if (getLevelOfAttribute(test[0]) == i) {
					TElement te = of.createTElement();
					te.setOccurrence(TOccurrence.valueOf(test[1]));
					te.setName(getLastAttribute(test[0]));
					TElement tep = getParentElement(test[0]);
					if (tep != null) {
						tep.getElement().add(te);
					}
				}
			}
		}
		try {
			JAXBContext jco = JAXBContext
					.newInstance("de.htwg_konstanz.infen.aufg3.inputXML.jaxbGenerated");
			Marshaller marshaller;

			marshaller = jco.createMarshaller();

			File outXML = new File(this.xmlFile);
			SchemaFactory sf = SchemaFactory
					.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
			Schema outputSchema = sf.newSchema(new File(this.xsdFile));
			marshaller.setSchema(outputSchema);
			marshaller
					.setEventHandler(new javax.xml.bind.helpers.DefaultValidationEventHandler());
			marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
			marshaller.setProperty("jaxb.noNamespaceSchemaLocation", (new File(
					this.xsdFile).getAbsolutePath()));
			marshaller.marshal(txdg, new FileOutputStream(outXML));
			System.out.println("Output path: " + outXML.getAbsolutePath());
		} catch (Exception e) {
			e.printStackTrace();
		}
		System.out.println("Done.");
	}

	private TElement getParentElement(String name) {
		String[] array = name.split("" + DataGuideHelper.itemSeperator);
		TElement te = txdg.getElement();
		// goto the end
		for (int i = 1; i < array.length - 1; i++) {
			List<TElement> lte = te.getElement();
			for (TElement tei : lte) {
				if (tei.getName().equalsIgnoreCase(array[i])) {
					te = tei;
					break;
				}
			}
		}
		return te;
	}

	private int getMaxLevel(Object[] aArray) {
		int max = 0;
		for (int i = 0; i < aArray.length; i++) {
			if (max < getLevelOfAttribute(aArray[i].toString())) {
				max = getLevelOfAttribute(aArray[i].toString());
			}
		}
		return max;
	}

	private int getLevelOfAttribute(String str) {
		return str.split("" + DataGuideHelper.itemSeperator).length;
	}

	private String getLastAttribute(String str) {
		return str.split("" + DataGuideHelper.itemSeperator)[getLevelOfAttribute(str) - 1];
	}
}
